home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 4
/
Aminet 4 - November 1994.iso
/
aminet
/
util
/
wb
/
spriteclock1_1.lha
/
SpriteClock.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-09
|
14KB
|
580 lines
#include <exec/alerts.h>
#include <workbench/startup.h>
#include <devices/input.h>
#include <intuition/intuitionbase.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/timer.h>
#include <proto/icon.h>
#include <proto/commodities.h>
#include <MyStartup.h>
#include <MyLib.h>
/***********************************************/
long Defaults[5]=
{
0,0,
1,
3,0
};
/***********************************************/
#define FONT_HEIGHT 7
struct SpriteImage
{
ULONG posctl;
ULONG Data[FONT_HEIGHT+1];
ULONG reserved;
};
/***********************************************/
struct Library *GfxBase;
struct Library *IconBase;
struct Library *CxBase;
struct IntuitionBase *IntuitionBase;
struct Device *TimerBase;
CxObj *Broker, *MouseMoveObject, *LeftButtonUpObject;
struct SpriteImage chip SpriteImage[2];
struct SimpleSprite SimpleSprite=
{
(UWORD *)&SpriteImage[1],
FONT_HEIGHT,
0,0,
-1
};
UWORD FontData[FONT_HEIGHT*3]=
{
0xE4EE,0xAEEE,0xEE00,
0xA422,0xA882,0xAA00,
0xA422,0xA882,0xAA00,
0xA4EE,0xEEE2,0xEE00,
0xA482,0x22A2,0xA200,
0xA482,0x22A2,0xA200,
0xE4EE,0x2EE2,0xEE00
};
struct EasyStruct EasyStruct=
{
sizeof(struct EasyStruct),
0,
"SpriteClock V1.1 Installation error",
NULL,
"Quit"
};
struct NewBroker NewBroker=
{
NB_VERSION,
"SpriteClock",
"SpriteClock V1.1 09-Jan-93 C. Stieber",
"Display a clock in a sprite",
0,
0,
0,
NULL,
0
};
char Version[]="$VER: SpriteClock 1.1 (09.01.93)";
struct SpriteImage *NewImage=&SpriteImage[0];
struct SpriteImage *OldImage=&SpriteImage[1];
struct timerequest timerequest;
WORD DeltaX, DeltaY;
struct
{
long *X;
long *Y;
long *SpriteNumber;
long *DrawingColor;
long *BackgroundColor;
} Arguments=
{
&Defaults[0],
&Defaults[1],
&Defaults[2],
&Defaults[3],
&Defaults[4],
};
struct RDArgs *RDArgs;
struct SignalSemaphore SpriteSemaphore;
WORD MouseX, MouseY;
/***********************************************/
void CloseAll(void)
{
if (Broker)
{
ActivateCxObj(Broker,0);
DeleteCxObjAll(Broker);
}
if (SimpleSprite.num!=-1) FreeSprite(SimpleSprite.num);
if (timerequest.tr_node.io_Device)
{
AbortIO((struct IORequest *)&timerequest);
WaitIO((struct IORequest *)&timerequest);
CloseDevice((struct IORequest *)&timerequest);
}
ReplyMessages(NewBroker.nb_Port);
if (RDArgs) FreeArgs(RDArgs);
CloseLibrary(CxBase);
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
}
/***********************************************/
void __regargs DrawDigit(UWORD Digit, int BitPos)
{
UWORD i;
ULONG *FontPointer;
ULONG FontMask;
UWORD *DestPointer;
UWORD DestValue;
Digit=Digit*4;
if (Digit<16)
{
FontMask=0xf0000000>>Digit;
FontPointer=(ULONG *)FontData;
}
else
{
FontMask=0xf0000000>>(Digit-=16);
FontPointer=(ULONG *)(FontData+1);
}
DestPointer=(UWORD *)(NewImage->Data);
for (i=0; i<FONT_HEIGHT; i++)
{
DestValue=((*FontPointer & FontMask)<<Digit)>>(BitPos+16);
if (*Arguments.DrawingColor & 1)
{
*DestPointer|=DestValue;
}
else
{
*DestPointer&=~DestValue;
}
DestPointer++;
if (*Arguments.DrawingColor & 2)
{
*DestPointer|=DestValue;
}
else
{
*DestPointer&=~DestValue;
}
DestPointer++;
FontPointer=(ULONG *)(((UWORD *)FontPointer)+3);
}
}
/***********************************************/
void DrawTime(void)
{
UWORD i;
ULONG *DestPointer;
ULONG Hour, Minute;
DestPointer=NewImage->Data;
Hour=(*Arguments.BackgroundColor & 1) ? 0xffff0000 : 0x00000000;
if (*Arguments.BackgroundColor & 2) Hour|=0x0000ffff;
for (i=0; i<FONT_HEIGHT; i++)
{
*DestPointer++=Hour;
}
Minute=timerequest.tr_time.tv_secs/60;
if (!(Hour=(Minute/60)%12))
{
Hour=12;
}
timerequest.tr_time.tv_secs=Minute*60+60;
timerequest.tr_time.tv_micro=0;
Minute%=60;
if (Hour>9)
{
DrawDigit(Hour/10,-1);
}
DrawDigit(Hour%10,2);
DrawDigit(Minute/10,8);
DrawDigit(Minute%10,12);
if (*Arguments.DrawingColor & 1)
{
((UWORD *)(NewImage->Data))[4]|=0x0200;
((UWORD *)(NewImage->Data))[10]|=0x0200;
}
else
{
((UWORD *)(NewImage->Data))[4]&=~0x0200;
((UWORD *)(NewImage->Data))[10]&=~0x0200;
}
if (*Arguments.DrawingColor & 2)
{
((UWORD *)(NewImage->Data))[5]|=0x0200;
((UWORD *)(NewImage->Data))[11]|=0x0200;
}
else
{
((UWORD *)(NewImage->Data))[5]&=~0x0200;
((UWORD *)(NewImage->Data))[11]&=~0x0200;
}
}
/***********************************************/
void RepositionSprite(void)
{
ObtainSemaphore(&SpriteSemaphore);
MoveSprite(NULL,&SimpleSprite,*Arguments.X>>1,*Arguments.Y>>1);
ReleaseSemaphore(&SpriteSemaphore);
}
/***********************************************/
void ShowNewSprite(void)
{
struct SpriteImage *Temp;
ChangeSprite(NULL,&SimpleSprite,(void *)NewImage);
RepositionSprite();
Temp=NewImage;
NewImage=OldImage;
OldImage=Temp;
}
/***********************************************/
BOOL CheckMousePosition(void)
{
DeltaX=MouseX-*Arguments.X;
DeltaY=MouseY-*Arguments.Y;
return(DeltaX>=0 && DeltaX<32 && DeltaY>=0 && DeltaY<(SimpleSprite.height<<1));
}
/***********************************************/
void GetMouse(void)
{
ULONG IntuitionLock;
IntuitionLock=LockIBase(0);
MouseX=IntuitionBase->MouseX;
MouseY=IntuitionBase->MouseY;
UnlockIBase(IntuitionLock);
}
/***********************************************/
CxMsg * __asm __saveds LeftButtonDown(register __a0 CxMsg *Message)
{
GetMouse();
if (CheckMousePosition())
{
DisposeCxMsg(Message);
Message=NULL;
ActivateCxObj(MouseMoveObject,TRUE);
ActivateCxObj(LeftButtonUpObject,TRUE);
}
return(Message);
}
/***********************************************/
CxMsg * __asm __saveds MouseMove(register __a0 CxMsg *Message)
{
GetMouse();
*Arguments.X=MouseX-DeltaX;
*Arguments.Y=MouseY-DeltaY;
RepositionSprite();
return(Message);
}
/***********************************************/
CxMsg * __asm __saveds LeftButtonUp(register __a0 CxMsg *Message)
{
DisposeCxMsg(Message);
Message=NULL;
ActivateCxObj(MouseMoveObject,FALSE);
ActivateCxObj(LeftButtonUpObject,FALSE);
return(Message);
}
/***********************************************/
void __regargs SimpleError(char *String)
{
if (CommandLineLength)
{
PutStr(String);
PutStr("\n");
}
else
{
EasyStruct.es_TextFormat=String;
EasyRequestArgs(NULL,&EasyStruct,NULL,NULL);
}
CloseAll();
exit(10);
}
/***********************************************/
void DosError(char *String, char *Filename)
{
long ErrorCode;
char ErrorBuffer[82];
APTR Arguments[2];
Arguments[0]=Filename;
Arguments[1]=ErrorBuffer;
if (!Fault(ErrorCode=IoErr(),NULL,ErrorBuffer,82))
{
sprintf(ErrorBuffer,"DOS-Error #%ld",ErrorCode);
}
if (CommandLineLength)
{
VPrintf(String,(long *)Arguments);
PutStr("\n");
}
else
{
EasyStruct.es_TextFormat=String;
EasyRequestArgs(NULL,&EasyStruct,NULL,Arguments);
}
CloseAll();
exit(10);
}
/***********************************************/
void ProcessMessages(void)
{
BOOL Quit;
CxMsg *Message;
Quit=FALSE;
while (!Quit)
{
WaitPort(NewBroker.nb_Port);
if (Message=(CxMsg *)GetMsg(NewBroker.nb_Port))
{
if ((struct Message *)Message==&timerequest)
{
GetSysTime(&timerequest.tr_time);
ObtainSemaphore(&SpriteSemaphore);
DrawTime();
ShowNewSprite();
ReleaseSemaphore(&SpriteSemaphore);
SendIO((struct IORequest *)&timerequest);
}
else
{
if (CxMsgType(Message)==CXM_COMMAND)
{
switch(CxMsgID(Message))
{
case CXCMD_DISABLE: ActivateCxObj(Broker,FALSE);
ActivateCxObj(MouseMoveObject,FALSE);
ActivateCxObj(LeftButtonUpObject,FALSE);
break;
case CXCMD_ENABLE: ActivateCxObj(Broker,TRUE);
break;
case CXCMD_UNIQUE:
case CXCMD_KILL: Quit=TRUE;
break;
default: break;
}
}
ReplyMsg((struct Message *)Message);
}
}
}
}
/***********************************************/
CxObj *AttachHandler(IX *InputXpression, CxMsg (* __asm __saveds Handler(register __a0 CxMsg *)))
{
CxObj *Filter, *Custom;
if (!(Filter=CxFilter(NULL)))
{
SimpleError("Unable to create a commodities filter object");
}
SetFilterIX(Filter,InputXpression);
AttachCxObj(Broker,Filter);
if (!(Custom=CxCustom(Handler,0)))
{
SimpleError("Unable to create a commodities custom object");
}
AttachCxObj(Filter,Custom);
return(Filter);
}
/***********************************************/
void main(void)
{
static IX InputXpression=
{
IX_VERSION,
IECLASS_RAWMOUSE,
IECODE_LBUTTON,0xffff,
IEQUALIFIER_LEFTBUTTON,IEQUALIFIER_LEFTBUTTON | IEQUALIFIER_MIDBUTTON | IEQUALIFIER_RBUTTON,
0
};
static char CommandTemplate[]="X/N/K,Y/N/K,SPRITE/N/K,DRAWING_COLOR=DC/N/K,BACKGROUND_COLOR=BC/N/K,PRIORITY=PRI/N/K";
static char *MyToolTypes[]=
{
"X",
"Y",
"SPRITE",
"DRAWING_COLOR",
"BACKGROUND_COLOR",
"PRIORITY"
};
int i;
char *String;
struct DiskObject *DiskObject;
if (!(IntuitionBase=(struct IntuitionBase *)OpenLibrary(&"Unable to open intuition.library"[15],0)))
{
if (CommandLineLength)
{
PutStr("Unable to open intuition.library");
PutStr("\n");
}
exit(10);
}
if (IntuitionBase->LibNode.lib_Version<37)
{
DisplayAlert(AT_Recovery,"\x00\x94\x10" "SpriteClock requires Kickstart V37 or later\x00",29);
CloseLibrary((struct Library *)IntuitionBase);
exit(10);
}
if (CommandLineLength)
{
if (!(RDArgs=ReadArgs(CommandTemplate,(long *)&Arguments,NULL)))
{
DosError("Error processing arguments: %s%s",NULL);
}
}
else
{
if (!(IconBase=OpenLibrary(&"Unable to open icon.library"[15],0)))
{
SimpleError("Unable to open icon.library");
}
if (!(DiskObject=GetDiskObject(Startup.WBenchMsg->sm_ArgList->wa_Name)))
{
CloseLibrary(IconBase);
DosError("Unable to read file %s:\n%s",Startup.WBenchMsg->sm_ArgList->wa_Name);
}
for (i=0; i<8; i++)
{
if (String=FindToolType(DiskObject->do_ToolTypes,MyToolTypes[i]))
{
StrToLong(String,&Defaults[i]);
}
}
FreeDiskObject(DiskObject);
CloseLibrary(IconBase);
}
if (!(GfxBase=OpenLibrary(&"Unable to open graphics.library"[15],0)))
{
SimpleError("Unable to open graphics.library");
}
if (!(CxBase=OpenLibrary("commodities.library",37)))
{
SimpleError("Unable to open commodities.library V37");
}
if (GetSprite(&SimpleSprite,*Arguments.SpriteNumber)==-1)
{
SimpleError("Unable to allocate a sprite");
}
SpriteImage[0].reserved=SpriteImage[1].reserved=0;
SpriteImage[0].Data[FONT_HEIGHT+1]=SpriteImage[1].Data[FONT_HEIGHT+1]=0;
InitSemaphore(&SpriteSemaphore);
NewBroker.nb_Port=&((struct Process *)FindTask(NULL))->pr_MsgPort;
if (!(Broker=CxBroker(&NewBroker,NULL)))
{
SimpleError("Unable to create a commodities broker");
}
AttachHandler(&InputXpression,LeftButtonDown);
InputXpression.ix_Code=IECODE_LBUTTON | IECODE_UP_PREFIX;
InputXpression.ix_QualMask=0;
LeftButtonUpObject=AttachHandler(&InputXpression,LeftButtonUp);
InputXpression.ix_Class=IECLASS_RAWMOUSE;
InputXpression.ix_CodeMask=0;
MouseMoveObject=AttachHandler(&InputXpression,MouseMove);
ActivateCxObj(LeftButtonUpObject,FALSE);
ActivateCxObj(MouseMoveObject,FALSE);
ActivateCxObj(Broker,TRUE);
timerequest.tr_node.io_Message.mn_ReplyPort=NewBroker.nb_Port;
if (OpenDevice(&"Unable to open timer.device"[15],UNIT_WAITUNTIL,(struct IORequest *)&timerequest,0))
{
SimpleError("Unable to open timer.device");
}
TimerBase=timerequest.tr_node.io_Device;
timerequest.tr_node.io_Command=TR_ADDREQUEST;
SendIO((struct IORequest *)&timerequest);
ProcessMessages();
CloseAll();
}